package org.example.aienglishapp_login.entity.login;

import com.fasterxml.jackson.annotation.JsonManagedReference;
import jakarta.persistence.*;
import jakarta.validation.constraints.Size;
import lombok.Getter;
import lombok.Setter;

/**
 * 用户个人资料实体类。
 * <p>
 * 该类用于表示用户的个人资料信息，并与数据库中的 "user_profiles" 表映射。
 * 每个用户都有一个对应的个人资料，其中包含昵称、头像、签名、性别和年龄等信息。
 *
 * @author xlj
 * @version 1.0
 * @since 2024-10-1
 */
@Getter
@Setter
@Entity
@Table(name = "user_profiles")
public class UserProfile {

    /**
     * 用户的唯一标识符。
     * 该字段是主键，并与 {@code User} 类的主键共享相同的值。
     */
    @Id
    private Long userId;

    /**
     * 关联的用户对象。
     * 使用一对一关系映射，并通过 {@code userId} 字段维护与用户的关系，避免循环依赖。
     */
    @OneToOne
    @MapsId
    @JsonManagedReference
    @JoinColumn(name = "user_id")
    private User user;

    /**
     * 用户的昵称。
     * 该字段的最大长度为20个字符。
     */
    @Size(max = 20)
    private String nickname;

    /**
     * 用户的头像链接。
     * 该字段的最大长度为255个字符。
     */
    @Size(max = 255)
    private String userAvatar;

    /**
     * 用户的个性签名。
     * 该字段的最大长度为100个字符。
     */
    @Size(max = 100)
    private String signature;

    /**
     * 用户的性别。
     * 性别字段限制为单个字符（例如："M" 或 "F"），并存储在数据库中。
     */
    @Column(name = "gender", columnDefinition = "CHAR(1)")
    private String gender;

    /**
     * 用户的年龄。
     * 年龄字段允许为空，且设定合法范围为0到150之间。
     */
    @Column(nullable = true)
    private Integer age;

    /**
     * 设置用户的年龄，并验证其合法性。
     *
     * @param age 用户的年龄
     */
    public void setAge(Integer age) {
        if (age != null && (age < 0 || age > 150)) {
            throw new IllegalArgumentException("年龄必须在0到150之间");
        }
        this.age = age;
    }

    @Override
    public String toString() {
        return "UserProfile{" +
                "userId=" + userId +
                ", nickname='" + nickname + '\'' +
                ", userAvatar='" + userAvatar + '\'' +
                ", signature='" + signature + '\'' +
                ", gender=" + gender +
                ", age=" + age +
                '}';
    }
}